package com.junglone.gateway.admin.service;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.junglone.gateway.admin.dao.MongoDao;
import com.junglone.gateway.admin.domain.TestPerson;

/**
 * Description:
 *
 * @author junglone: <a href="mailto:cjlnzb@hotmail.com">cjlnzb@hotmail.com</a>
 * @since 2021/03/23 18:09
 */
@Service
public class MongoTestService {

    private static final Logger LOGGER = LoggerFactory.getLogger(MongoTestService.class);

    @Resource
    private MongoDao<TestPerson> mongoTestDao;

    public TestPerson insert() {

        TestPerson testPerson = new TestPerson();
        testPerson.setName("hello");
        testPerson.setPhone("13512341234");
        testPerson.setSex(1);
        testPerson.setAge(18);
        testPerson.setAddress("China");
        testPerson.setCreateTime(new Date());

        return mongoTestDao.insert(testPerson);
    }

    public List<TestPerson> findList() {

        String strId = "605b0b7667f6354747a3b9f5";
        Criteria criteria = Criteria.where("id").gte(new ObjectId(strId));
        Query query = new Query();
        query.addCriteria(criteria);
        query.with(Sort.by("id").ascending());
        query.limit(5);

        return mongoTestDao.findAll(query, TestPerson.class);
    }

    public List<TestPerson> findList(Map<String, Object> mapParam) {

        String strId = mapParam.get("id").toString();

        Criteria criteria = Criteria.where("id").gte(new ObjectId(strId));
        Query query = new Query();
        query.addCriteria(criteria)
                .with(Sort.by("id").ascending())
                .skip(0)
                .limit(5);

        return mongoTestDao.findAll(query, TestPerson.class);
    }

    public Page<TestPerson> findListByPage(Map<String, Object> mapParam) {
        String strId = mapParam.get("id").toString();
        int nPageNo = Integer.parseInt(mapParam.get("pageNo").toString());
        String strSortBy = mapParam.get("sortBy").toString();

        Criteria criteria = Criteria.where("id").gte(new ObjectId(strId));
        Pageable pageable = PageRequest.of(nPageNo, 4, Sort.by(strSortBy).ascending());
        LOGGER.info("pageable ==== {}", pageable);

        Query query = new Query();
        query.addCriteria(criteria).with(pageable);

        long lCount = mongoTestDao.count(query, TestPerson.class);
        LOGGER.info("lCount ==== {}", lCount);

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            LOGGER.info("pageable ==== {}", objectMapper.writeValueAsString(pageable));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        List<TestPerson> testPersonList = mongoTestDao.findAll(query, TestPerson.class);
        Page<TestPerson> testPersonPage = new PageImpl<>(testPersonList, pageable, lCount);
        LOGGER.info("people ==== {}", testPersonPage);
        try {
            LOGGER.info("people ==== {}", objectMapper.writeValueAsString(testPersonPage));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return testPersonPage;
    }

    public UpdateResult update(Map<String, Object> mapParam) {

        String strId = mapParam.get("id").toString();
        Criteria criteria = Criteria.where("id").is(strId);
        Query query = new Query();
        query.addCriteria(criteria);

        String strUser = "{\"id\":\"606599e794399f209bf7a140\",\"name\":\"test-update\",\"phone\":\"13512341234\",\"address\":\"中国\",\"sex\":1,\"age\":16}";

        Update update = Update.fromDocument(Document.parse(strUser));
        update.currentDate("createTime");
        update.currentDate("updateTime");

        return mongoTestDao.update(query, update, TestPerson.class);
    }

    public DeleteResult remove(String strId) {
        Criteria criteria = Criteria.where("id").is(strId);
        Query query = new Query();
        query.addCriteria(criteria);

        return mongoTestDao.remove(query, TestPerson.class);
    }
}
